package com.yang.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mzt.logapi.starter.annotation.LogRecord;
import com.yang.dao.entity.OrdersDO;
import com.yang.dao.mapper.OrdersMapper;
import com.yang.dto.req.OrderSaveReqDTO;
import com.yang.dto.req.OrdersPageQueryReqDTO;
import com.yang.dto.resp.OrdersPageQueryRespDTO;
import com.yang.exception.ClientException;
import com.yang.service.OrdersService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;


/**
 * 订单业务实现层
 * 作者：孤城暖阳y
 * 开发时间：2025-02-25
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersDO> implements OrdersService {

    private final OrdersMapper ordersMapper;
    private final StringRedisTemplate stringRedisTemplate;
    private final RedissonClient redissonClient;

    @SneakyThrows
    @LogRecord(
            success = """
                    订单号：{{#requestParam.ordersId}}， \
                    用户ID：{{#requestParam.userId}}， \
                    支付方式：{{#requestParam.paymentMethod}}， \
                    开始时间：{{#requestParam.startTime}}， \
                    结束时间：{{#requestParam.endTime}};
                    """,
            type = "OrderQuery",
            bizNo = "{{#requestParam.ordersId}}",
            extra = "{{#requestParam.toString()}}"
    )
    @Override
    public IPage<OrdersPageQueryRespDTO> pageQueryOrders(OrdersPageQueryReqDTO requestParam) {
        // 构建分页查询模板 LambdaQueryWrapper
        // 使用 LambdaQueryWrapper 构建查询条件
        LambdaQueryWrapper<OrdersDO> queryWrapper = Wrappers.lambdaQuery(OrdersDO.class)
                // 如果订单id不为空，添加订单id查询条件
                .eq(Objects.nonNull(requestParam.getOrdersId()), OrdersDO::getOrdersId, requestParam.getOrdersId())
                // 如果用户id不为空，添加用户id查询条件
                .eq(Objects.nonNull(requestParam.getUserId()), OrdersDO::getUserId, requestParam.getUserId())
                // 如果支付方式不为空，添加支付方式查询条件
                .like(Objects.nonNull(requestParam.getPaymentMethod()), OrdersDO::getPaymentMethod, requestParam.getPaymentMethod())
                // 替换原来的创建时间条件为范围查询
                .between(Objects.nonNull(requestParam.getStartTime()) && Objects.nonNull(requestParam.getEndTime()),
                        OrdersDO::getCreateTime,
                        requestParam.getStartTime(),
                        requestParam.getEndTime())
                .orderByDesc(OrdersDO::getCreateTime);
        // 执行分页查询，返回查询结果
        IPage<OrdersDO> page = ordersMapper.selectPage(requestParam, queryWrapper);
        // 转换数据持久层实体为响应数据传输对象
        return page.convert(each -> BeanUtil.toBean(each, OrdersPageQueryRespDTO.class));
    }


    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @LogRecord(
            success = """
                    订单号：{{#requestParam.ordersId}}， \
                    用户ID：{{#requestParam.userId}}， \
                    订单总金额：{{#requestParam.totalAmount}}， \
                    订单状态：{{#requestParam.status}}， \
                    支付方式：{{#requestParam.paymentMethod}}， \
                    备注：{{#requestParam.notes}};
                    """,
            type = "OrdersSave",
            bizNo = "{{#requestParam.ordersId}}",
            extra = "{{#requestParam.toString()}}"
    )
    public void saveOrders(OrderSaveReqDTO requestParam) {
        // 查询用户和订单id是否对应
        LambdaQueryWrapper<OrdersDO> checkInfo = Wrappers.lambdaQuery(OrdersDO.class)
                .eq(OrdersDO::getOrdersId, requestParam.getOrdersId())
                .eq(OrdersDO::getUserId, requestParam.getUserId());
        OrdersDO ordersDO = ordersMapper.selectOne(checkInfo);
        if (Objects.isNull(ordersDO)) {
            throw new ClientException("查询到的数据为空！");
        }

        LambdaQueryWrapper<OrdersDO> queryWrapper = Wrappers.lambdaQuery(OrdersDO.class)
                .eq(OrdersDO::getOrdersId, requestParam.getOrdersId())
                .eq(Objects.nonNull(requestParam.getUserId()), OrdersDO::getUserId, requestParam.getUserId())
                // 如果订单总金额不为空，添加订单总金额查询条件
                .eq(Objects.nonNull(requestParam.getTotalAmount()), OrdersDO::getTotalAmount, requestParam.getTotalAmount())
                // 如果支付方式不为空，添加支付方式查询条件
                .eq(Objects.nonNull(requestParam.getPaymentMethod()), OrdersDO::getPaymentMethod, requestParam.getPaymentMethod())
                // 如果订单备注不为空，添加订单备注查询条件
                .eq(Objects.nonNull(requestParam.getNotes()), OrdersDO::getNotes, requestParam.getNotes());
        // 执行更新操作
        ordersMapper.update(BeanUtil.toBean(requestParam, OrdersDO.class), queryWrapper);
    }

    @Override
    public Long getOrderCount() {
        return ordersMapper.selectCount(null);
    }

    @Override
    public Long getOrderCountToday() {
        // 获取当天开始和结束时间
        LocalDate today = LocalDate.now();
        LocalDateTime startOfDay = today.atStartOfDay();
        LocalDateTime endOfDay = today.plusDays(1).atStartOfDay();

        // 构建查询条件，查询今天的订单
        LambdaQueryWrapper<OrdersDO> queryWrapper = Wrappers.lambdaQuery(OrdersDO.class)
                .between(OrdersDO::getCreateTime, startOfDay, endOfDay);
        return ordersMapper.selectCount(queryWrapper);
    }
}
